package com.winsdom.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.winsdom.context.BaseContext;
import com.winsdom.dto.resource.ChageTablesDto;
import com.winsdom.dto.resource.PayFeesRecordDto;
import com.winsdom.entity.*;
import com.winsdom.mapper.*;
import com.winsdom.result.Result;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.winsdom.dto.*;
import com.winsdom.entity.Category;
import com.winsdom.entity.Resource;
import com.winsdom.entity.SplitMerge;
import com.winsdom.exception.BaseException;
import com.winsdom.mapper.CategoryMapper;
import com.winsdom.mapper.ResourceMapper;
import com.winsdom.mapper.SplitMergeMapper;
import com.winsdom.result.PageResult;
import com.winsdom.service.IResourceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.winsdom.vo.ResourceVO;
import com.winsdom.vo.SplitMergeVo;
import com.winsdom.vo.resource.BillsVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import com.winsdom.vo.resource.ThreeTablesVo;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.springframework.transaction.annotation.Transactional;
import static com.winsdom.enums.RedisKey.ORGANIZATION_FLOOR;


/**
 * <p>
 * 资源信息表 服务实现类
 * </p>
 *
 * @author 
 * @since 2025-05-12
 */
@Service
@Slf4j
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements IResourceService {
    @Autowired
    private ThreeTablesMapper threeTablesMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private ReadingRecordMapper readingRecordMapper;
    @Autowired
    private TableReplacementMapper tableReplacementMapper;
    @Autowired
    protected ResourceMapper resourceMapper;
    @Autowired
    protected SplitMergeMapper splitMergeMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private BillsMapper billsMapper;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public Result getThreeTables(Long categoryId) {
        List<ThreeTablesVo> threeTablesVos = threeTablesMapper.getYThreeTables(categoryId);
        return Result.success(threeTablesVos);
    }

    @Override
    public Result stopThreeTables(Integer id) {
        int i = threeTablesMapper.update(null, new UpdateWrapper<ThreeTables>().eq("id", id).set("status", 0));
        if(i>0){
            return Result.success("停用成功");
        }
        return Result.error("系统错误!");
    }

    @Override
    public Result getResourceName(Integer id) {
        ThreeTables threeTables = threeTablesMapper.selectById(id);
        if(threeTables==null){
            return Result.error("系统错误!");
        }

        // 封装所属资源
        List<String> pathNames = new ArrayList<>();
        Long currentId = Long.valueOf(threeTables.getCategoryId());

        while (currentId != null && currentId != 0) {
            Category category = categoryMapper.selectById(currentId);
            if (category == null) {
                break;
            }

            pathNames.add(category.getName());

            // 如果当前已经是组织(type=1)，则停止
            if (category.getType() == 1) {
                break;
            }

            currentId = category.getParentId();
        }
        // 反转顺序，从组织到资源
        Collections.reverse(pathNames);

        return Result.success(String.join("-", pathNames));
    }

    @Override
    @Transactional
    public Result changeTable(ChageTablesDto chageTablesDto) {
        ThreeTables threeTables = threeTablesMapper.selectById(chageTablesDto.getId());
        if(threeTables==null){
            return Result.error("系统错误!");
        }
        ThreeTables threeTables1 = new ThreeTables();
        threeTables1.setCategoryId(threeTables.getCategoryId());
        threeTables1.setType(threeTables.getType());
        threeTables1.setNumber(chageTablesDto.getNumber());
        threeTables1.setName(chageTablesDto.getName());
        threeTables1.setSwot(chageTablesDto.getSwot());
        threeTables1.setReadingCycle(threeTables.getReadingCycle());
        threeTables1.setRemark(threeTables.getRemark());
        threeTables1.setMagnification(threeTables.getMagnification());
        threeTables1.setStatus(1);
        threeTables1.setUserId(threeTables.getUserId());
        threeTables1.setCreateTime(LocalDateTime.now());
        threeTables1.setUpdateTime(LocalDateTime.now());
        //比如：SELECT * FROM three_tables WHERE category_id = 19 AND (name = 'S101水表' OR number = 'S101')
        ThreeTables threeTables2 = threeTablesMapper.selectOne(
                new LambdaQueryWrapper<ThreeTables>()
                        .eq(ThreeTables::getCategoryId, threeTables.getCategoryId())  // category_id=19（必须）
                        .and(wrapper -> wrapper
                                .eq(ThreeTables::getName, chageTablesDto.getName())      // name='S101水表'
                                .or()
                                .eq(ThreeTables::getNumber, chageTablesDto.getNumber())   // OR number='S101'
                        )
        );
        if(threeTables2!=null){
            return Result.error("该三表编号，三表名称已存在!");
        }
        Integer count = threeTablesMapper.selectCount(new LambdaQueryWrapper<ThreeTables>().eq(ThreeTables::getCategoryId, threeTables.getCategoryId()).eq(ThreeTables::getStatus,1));
        if(count>=100){
            return Result.error("该资源下三表数量已达上限，请先停用后重试!");
        }
        threeTablesMapper.insert(threeTables1);    //插入新的三表

        threeTablesMapper.update(null,new UpdateWrapper<ThreeTables>().eq("id",chageTablesDto.getId()).set("status",0));  //修改旧表为停用

        //确保旧表的 最后一次读数 被正确记录在 reading_record 表中（用于后续计费）
        readingRecordMapper.update(null,new UpdateWrapper<ReadingRecord>().eq("table_id",chageTablesDto.getId())
                .set("current_reading",chageTablesDto.getCurrentReading()));

        TableReplacement tableReplacement = new TableReplacement();
        tableReplacement.setOldTableId(chageTablesDto.getId());
        tableReplacement.setNewTableId(threeTables1.getId());
        tableReplacement.setLastReading(chageTablesDto.getCurrentReading());
        tableReplacement.setReplacementTime(LocalDateTime.now());
        tableReplacement.setOperatorId(threeTables.getUserId());
        tableReplacementMapper.insert(tableReplacement);   //插入三表更换记录表
        return Result.success();
    }

    @Override
    public Result PayFeesRecord(PayFeesRecordDto payFeesRecordDto) {
        List<BillsVo> bills=billsMapper.selectListForParams(payFeesRecordDto);
        return Result.success(bills);
    }

    @Override
    public PageResult getResourceList(Long id, ResourceFilterRequest request) {
        // 1. 构建分类树
        CategoryTreeNodes node = resourceMapper.getNodeById(id);
        if (node == null) {
            return new PageResult(0, Collections.emptyList(), request.getPageNum(), request.getPageSize());
        }
        buildSubTree1(node);

        // 2. 收集type为6的分类ID
        List<Long> categoryIds = new ArrayList<>();
        collectCategoryIdsByType(node, categoryIds, 6);

        if (CollectionUtils.isEmpty(categoryIds)) {
            return new PageResult(0, Collections.emptyList(), request.getPageNum(), request.getPageSize());
        }

        // 3. 转换为Integer类型列表
        List<Integer> validCategoryIds = categoryIds.stream()
                .filter(Objects::nonNull)
                .map(Long::intValue)
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(validCategoryIds)) {
            return new PageResult(0, Collections.emptyList(), request.getPageNum(), request.getPageSize());
        }

        // 4. 构建分页查询条件
        Page<Resource> page = new Page<>(request.getPageNum(), request.getPageSize());

        // 5. 构建动态查询条件
        QueryWrapper<Resource> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("category_id", validCategoryIds);

        // 添加其他筛选条件
        if (org.springframework.util.StringUtils.hasText(request.getResourceNumber())) {
            queryWrapper.like("resource_number", request.getResourceNumber());
        }
        if (org.springframework.util.StringUtils.hasText(request.getResourceName())) {
            queryWrapper.like("resource_name", request.getResourceName());
        }
        if (org.springframework.util.StringUtils.hasText(request.getResourceStatus())) {
            queryWrapper.eq("resource_status", request.getResourceStatus());
        }
        if (org.springframework.util.StringUtils.hasText(request.getResourceType())) {
            queryWrapper.eq("resource_type", request.getResourceType());
        }

        // 6. 执行分页查询
        IPage<Resource> resourcePage = resourceMapper.selectPage(page, queryWrapper);

        // 7. 转换为现有的PageResult格式
        return new PageResult(
                resourcePage.getTotal(),
                resourcePage.getRecords(),
                (int) resourcePage.getCurrent(),
                (int) resourcePage.getSize()
        );
    }

    @Override
    public void addResource(ResourceDTO resourceDTO) {
        //判断父级分类是否为楼层
        Category parentCategory = categoryMapper.selectById(resourceDTO.getParentId());
        if (parentCategory.getType() != 5) {
            throw new BaseException("父级分类不是楼层");
        }
        // 1. 检查同级分类下是否存在同名资源
        List<Category> existingCategories = categoryMapper.selectByNameAndParentId(
                resourceDTO.getParentId(),
                resourceDTO.getResourceName(),
                6 // 资源类型
        );

        if (!existingCategories.isEmpty()) {
            throw new BaseException("同级分类下已存在同名资源");
        }

        // 2. 构建并插入category记录
        Category category = new Category()
                .setName(resourceDTO.getResourceName())
                .setParentId(resourceDTO.getParentId())
                .setType(6)
                .setStatus(1);

        int rows = categoryMapper.insert(category);
        if (rows != 1) {
            throw new BaseException("创建资源分类失败");
        }

        // 3. 构建并插入resource记录
        Resource resource = new Resource()
                .setCategoryId(category.getId().intValue())
                .setResourceName(resourceDTO.getResourceName())
                .setResourceType(resourceDTO.getResourceType())
                .setResourceNumber(resourceDTO.getResourceNumber())
                .setVirtualResources(resourceDTO.getVirtualResources())
                .setBuildingArea(resourceDTO.getBuildingArea())
                .setInteriorArea(resourceDTO.getInteriorArea())
                .setResourceStatus("未接房")
                .setCapacity(resourceDTO.getCapacity())
                .setUserId(1L)
                .setCreateTime(LocalDateTime.now())
                .setUpdateTime(LocalDateTime.now());
        resourceMapper.insert(resource);
    }

    @Override
    public Result update(ResourceUpdDTO resourceUpdDTO) {
        try {
            //获取当前资源信息
            Resource resource = resourceMapper.getById(resourceUpdDTO.getId());
            //判断父级分类是否为楼层
            Category parentCategory = categoryMapper.selectById(resourceUpdDTO.getParentId());
            if (parentCategory.getType() != 5) {
                throw new BaseException("父级分类不是楼层");
            }
            // 1. 检查同级分类下是否存在同名资源，并且过滤掉当前资源
            List<Category> existingCategories = categoryMapper.selectByNameAndParentId(
                    resourceUpdDTO.getParentId(),
                    resourceUpdDTO.getResourceName(),
                    6) // 6为资源类型
                    // 这里假设Category的id字段是Long类型，根据实际情况修改
                    .stream()
                    .filter(category -> !Long.valueOf(resource.getCategoryId()).equals(category.getId()))
                    .collect(Collectors.toList());
            if (!existingCategories.isEmpty()) {
                throw new BaseException("同级分类下已存在同名资源");
            }
            //检查输入的建筑面积和套内面积是否合法
            if (resourceUpdDTO.getInteriorArea().compareTo(resourceUpdDTO.getBuildingArea()) > 0) {
                throw new BaseException("套内面积不能大于建筑面积");
            }

            // 2. 构建并修改category记录
            Category category = new Category()
                    .setId(Long.valueOf(resource.getCategoryId()))
                    .setName(resourceUpdDTO.getResourceName())
                    .setParentId(resourceUpdDTO.getParentId());
            int rows = categoryMapper.updateById(category);
            if (rows != 1) {
                throw new BaseException("修改资源分类失败");
            }

            // 3. 构建并修改resource记录
            BeanUtils.copyProperties(resourceUpdDTO, resource);
            resourceMapper.update(resource);
            return Result.success("修改成功");
        }  catch (BaseException e) {
            throw new BaseException(e.getMessage());
        }
    }

    @Override
    public Result splitResource(Long id, ResourceSplitDTO resourceSplitDTO) {
        try {
        //获取当前资源信息
        Resource resource = resourceMapper.getById(id);
        if (resource == null) {
            throw new BaseException("资源不存在或已停用");
        }
        // 检查新资源建筑面积和套内面积是否符合要求
        BigDecimal newResourceBuildingArea = resourceSplitDTO.getBuildingArea();
        BigDecimal newResourceInnerArea = resourceSplitDTO.getInteriorArea();

        if (newResourceBuildingArea.compareTo(resource.getBuildingArea()) > 0) {
            throw new BaseException("新资源建筑面积不能大于被拆分资源的建筑面积");
        }
        if (newResourceInnerArea.compareTo(resource.getInteriorArea()) > 0) {
            throw new BaseException("新资源套内面积不能大于被拆分资源的套内面积");
        }
        if (newResourceInnerArea.compareTo(newResourceInnerArea) > 0) {
            throw new BaseException("套内面积不能大于建筑面积");
        }
        //获取父组织id
        Long parentId = categoryMapper.getById(resource.getCategoryId()).getParentId();
        // 1. 检查同级分类下是否存在同名资源
        List<Category> existingCategories = categoryMapper.selectByNameAndParentId(
                parentId,
                resourceSplitDTO.getResourceName(),
                6 // 资源类型
        );

        if (!existingCategories.isEmpty()) {
            throw new BaseException("同级分类下已存在同名资源");
        }

        // 2. 构建并插入category记录
        Category category = new Category()
                .setName(resourceSplitDTO.getResourceName())
                .setParentId(parentId)
                .setType(6)
                .setStatus(1);

        int rows = categoryMapper.insert(category);
        if (rows != 1) {
            throw new BaseException("创建资源分类失败");
        }

        // 3. 构建并插入resource记录
        Resource newresource = new Resource()
                .setCategoryId(category.getId().intValue())
                .setResourceName(resourceSplitDTO.getResourceName())
                .setResourceType(resource.getResourceType())
                .setResourceNumber(resourceSplitDTO.getResourceNumber())
                .setVirtualResources(0)
                .setBuildingArea(resourceSplitDTO.getBuildingArea())
                .setInteriorArea(resourceSplitDTO.getInteriorArea())
                .setResourceStatus("未接房")
                .setCapacity(resourceSplitDTO.getCapacity())
                .setUserId(1L)
                .setCreateTime(LocalDateTime.now())
                .setUpdateTime(LocalDateTime.now());
        // 保存新资源
        int saveNewResource = resourceMapper.insert(newresource);
        if (saveNewResource > 0) {
            // 更新被拆分资源的建筑面积和套内面积
            resource.setBuildingArea(resource.getBuildingArea().subtract(newresource.getBuildingArea()));
            resource.setInteriorArea(resource.getInteriorArea().subtract(newresource.getInteriorArea()));
            int updateOriginalResource = resourceMapper.updateById(resource);
            if (updateOriginalResource <= 0) {
                throw new BaseException("更新被拆分资源的建筑面积和套内面积失败");
            }
            //往split_merge表中插入数据
            SplitMerge splitMerge = new SplitMerge()
                    .setResourceId(resource.getId())
                    .setNewResourceId(newresource.getId())
                    .setBeforeBuildingArea(resource.getBuildingArea().add(newresource.getBuildingArea()))
                    .setBeforeInteriorArea(resource.getInteriorArea().add(newresource.getInteriorArea()))
                    .setAfterBuildingArea(resource.getBuildingArea())
                    .setAfterInteriorArea(resource.getInteriorArea())
                    .setType(0);
            splitMergeMapper.insert(splitMerge);
        }
        } catch (BaseException e) {
            throw new BaseException(e.getMessage());
        }
        return Result.success("资源拆分成功");
    }
    @Override
    public Result getCommonResource(Long id) {
        //获取父节点id
        Long parentId = categoryMapper.getById(resourceMapper.getById(id).getCategoryId()).getParentId();
        //获取父节点下的所有子节点
        List<CategoryTreeNodes> nodes = resourceMapper.getChildrenByParentId1(parentId);
        //遍历子节点，排除本条资源并添加到list中
        List<Long> categoryIds = new ArrayList<>();
        Resource currentResource = resourceMapper.getById(id);
        Long currentCategoryId = Long.valueOf(currentResource.getCategoryId());

        for (CategoryTreeNodes node : nodes) {
            if (!node.getId().equals(currentCategoryId)) {
                categoryIds.add(node.getId());
            }
        }
        if (categoryIds.isEmpty()) {
            throw new BaseException("没有可合并的资源");
        }
        //根据categoryIds获取所有资源
        List<Resource> resources = resourceMapper.getByCategoryId(categoryIds);
        //筛选状态为未接房，并且为实体的资源
        resources = resources.stream()
                .filter(resource -> resource.getResourceStatus().equals("未接房"))
                .filter(resource -> resource.getVirtualResources() == 0)
                .collect(Collectors.toList());
        if (resources.isEmpty()) {
            throw new BaseException("没有可合并的资源");
        }
        //将本条资源作为第一条数据插入返回结果中
        resources.add(0, currentResource);
        return Result.success(resources);
    }
    @Override
    public Result mergeResource(MergeResourceDTO mergeResourceDTO) {
        // 校验参数
        if (mergeResourceDTO.getSourceResourceIds() == null || mergeResourceDTO.getSourceResourceIds().isEmpty()) {
            throw new BaseException("请选择要合并的资源");
        }
        if (mergeResourceDTO.getSourceResourceIds().contains(mergeResourceDTO.getTargetResourceId())) {
            throw new BaseException("目标资源不能包含在合并资源列表中");
        }

        // 获取目标资源信息
        Resource targetResource = resourceMapper.getById(mergeResourceDTO.getTargetResourceId());
        if (targetResource == null) {
            throw new BaseException("目标资源不存在或已停用");
        }
        //记录目标资源信息
        BigDecimal  beforeBuildingArea = targetResource.getBuildingArea();
        BigDecimal  beforeInteriorArea = targetResource.getInteriorArea();

        // 获取所有源资源信息并校验
        List<Resource> sourceResources = new ArrayList<>();
        for (Long sourceId : mergeResourceDTO.getSourceResourceIds()) {
            Resource sourceResource = resourceMapper.getById(sourceId);
            if (sourceResource == null) {
                throw new BaseException("源资源中存在不存在或已停用资源");
            }
            sourceResources.add(sourceResource);
        }

        // 计算合并后的总面积
        BigDecimal totalBuildingArea = targetResource.getBuildingArea();
        BigDecimal totalInteriorArea = targetResource.getInteriorArea();

        for (Resource source : sourceResources) {
            totalBuildingArea = totalBuildingArea.add(source.getBuildingArea());
            totalInteriorArea = totalInteriorArea.add(source.getInteriorArea());
        }

        // 校验套内面积不能大于建筑面积
        if (totalInteriorArea.compareTo(totalBuildingArea) > 0) {
            throw new BaseException("合并后的套内面积不能大于建筑面积");
        }

        // 开始事务性操作
        try {
            // 更新目标资源面积
            targetResource.setBuildingArea(totalBuildingArea);
            targetResource.setInteriorArea(totalInteriorArea);
            targetResource.setUpdateTime(LocalDateTime.now());
            int updateTarget = resourceMapper.updateById(targetResource);
            if (updateTarget <= 0) {
                throw new BaseException("更新目标资源失败");
            }

            // 禁用源资源
            for (Resource source : sourceResources) {
                source.setResourceStatus("已停用");
                int disableSource = resourceMapper.updateById(source);
                if (disableSource <= 0) {
                    throw new BaseException("禁用源资源失败");
                }
            }
            SplitMerge splitMerge = new SplitMerge()
                    .setResourceId(targetResource.getId())
                    .setNewResourceId(null)
                    .setBeforeBuildingArea(beforeBuildingArea)
                    .setBeforeInteriorArea(beforeInteriorArea)
                    .setAfterBuildingArea(targetResource.getBuildingArea())
                    .setAfterInteriorArea(targetResource.getInteriorArea())
                    .setType(1); // 1表示合并
            splitMergeMapper.insert(splitMerge);
            return Result.success("资源合并成功");
        } catch (Exception e) {
            throw new BaseException("资源合并失败：" + e.getMessage());
        }
    }
    @Override
    public ResourceVO getResourceById(Long id) {
        Resource resource = resourceMapper.getById(id);
        ResourceVO resourceVO = new ResourceVO();
        Integer parentCategoryId = Math.toIntExact(categoryMapper.getById(resource.getCategoryId()).getParentId());
        List<SplitMergeVo> splitMergeLists = splitMergeMapper.getByResourceId(id);
        resourceVO.setParentCategoryName(categoryMapper.getById(parentCategoryId).getName());
        resourceVO.setParentId(parentCategoryId);
        resourceVO.setSplitMergeLists(splitMergeLists);
        BeanUtils.copyProperties(resource, resourceVO);
        return resourceVO;
    }

    @Override
    public void deleteById(Long id) {
        Resource resource = resourceMapper.getById(id);

        if (resource == null) {
            throw new BaseException("资源不存在或已禁用，无法删除");
        }

        if ("未接房".equals(resource.getResourceStatus())) {
            resourceMapper.deleteById(id);
            Category category = categoryMapper.selectById(resource.getCategoryId());
            if (category != null) {
                category.setStatus(0);
                categoryMapper.updateById(category);
            }
            splitMergeMapper.delete(new QueryWrapper<SplitMerge>().eq("resource_id", id));
        } else {
            throw new BaseException("只能删除未接房资源");
        }
    }

    @Override
    public List<CategoryTreeNodes> getOrganizationTree() {
        //获取当前账号信息
        Long userId = Long.valueOf(BaseContext.getCurrentId());
        if (userId == null) {
            throw new BaseException("该账号异常");
        }
        log.info("用户id：{}",userId);

        String cacheKey = ORGANIZATION_FLOOR.getValue()+userId;
        List<CategoryTreeNodes> resourceTree = null;
        try {
            //从 Redis 获取缓存数据
            resourceTree = (List<CategoryTreeNodes>) redisTemplate.opsForValue().get(cacheKey);
        } catch (Exception e) {
            log.error("从Redis获取组织树数据失败: {}", e.getMessage(), e);
        }
        if (resourceTree == null) {
            try {
                // 查询数据库
                List<Long> authorizedBuildingIds = resourceMapper.getauthorizedBuildingIds(userId);
                Long orgId = sysUserMapper.selectById(userId).getCategoryId();
                resourceTree = getAuthorizedResourceTree(orgId, new HashSet<>(authorizedBuildingIds));
                if (resourceTree != null) {
                    //将查询结果存入Redis缓存
                    redisTemplate.opsForValue().set(cacheKey, resourceTree, 1, TimeUnit.HOURS);
                }
            } catch (Exception e) {
                log.error("查询组织树数据失败: {}", e.getMessage(), e);
                // 数据库查询失败时，返回错误响应
                return null;
            }
        }
        return resourceTree;
    }

    /**
     * 递归收集节点及其所有子节点中type等于指定值的categoryId
     */
    private void collectCategoryIdsByType(CategoryTreeNodes node, List<Long> categoryIds, int targetType) {
        if (node == null) {
            return;
        }

        // 如果当前节点的type等于目标类型，则添加到结果列表
        if (Objects.equals(node.getType(), targetType)) {
            categoryIds.add(node.getId());
        }

        // 递归处理子节点
        List<CategoryTreeNodes> children = node.getChildren();
        if (children != null && !children.isEmpty()) {
            for (CategoryTreeNodes child : children) {
                collectCategoryIdsByType(child, categoryIds, targetType);
            }
        }
    }

    /**
     * 递归构建完整子树
     */
    private void buildSubTree(CategoryTreeNodes parentNode) {
        // 查询子节点
        List<CategoryTreeNodes> children = resourceMapper.getChildrenByParentId(parentNode.getId());

        if (!children.isEmpty()) {
            parentNode.setChildren(children);
            // 递归处理每个子节点
            for (CategoryTreeNodes child : children) {
                buildSubTree(child);
            }
        }
    }

    private void buildSubTree1(CategoryTreeNodes parentNode) {
        List<CategoryTreeNodes> children = resourceMapper.getChildrenByParentId1(parentNode.getId());

        if (!children.isEmpty()) {
            parentNode.setChildren(children);
            for (CategoryTreeNodes child : children) {
                buildSubTree1(child);
            }
        }
    }
    public List<CategoryTreeNodes> getAuthorizedResourceTree(Long orgId, Set<Long> authorizedBuildingIds) {
        // 1. 查询所有分类数据
        List<Category> allCategories = categoryMapper.selectList(new LambdaQueryWrapper<Category>().eq(Category::getStatus, 1));

        // 2. 转换为节点映射
        Map<Long, CategoryTreeNodes> idNodeMap = new HashMap<>();
        for (Category category : allCategories) {
            CategoryTreeNodes node = new CategoryTreeNodes();
            BeanUtils.copyProperties(category, node);
            node.setChildren(new ArrayList<>());
            idNodeMap.put(node.getId(), node);
        }

        // 3. 构建父子关系
        for (CategoryTreeNodes node : idNodeMap.values()) {
            CategoryTreeNodes parent = idNodeMap.get(node.getParentId());
            if (parent != null) {
                parent.getChildren().add(node);
            }
        }

        // 4. 从 orgId 本身作为根节点开始过滤
        CategoryTreeNodes root = idNodeMap.get(orgId);
        if (root == null) {
            return Collections.emptyList(); // orgId 不存在
        }

        CategoryTreeNodes filtered = filterResourceUnderAuthorizedBuildings(root, authorizedBuildingIds);
        if (filtered == null) {
            return Collections.emptyList(); // 无授权资源
        }

        // 返回带 orgId 的整棵子树
        return Collections.singletonList(filtered);
    }
    private CategoryTreeNodes filterResourceUnderAuthorizedBuildings(CategoryTreeNodes node, Set<Long> authorizedBuildingIds) {
        if (node.getType() == 3 && !authorizedBuildingIds.contains(node.getId())) {   //是否在楼盘ID集合中
            return null;
        }

        List<CategoryTreeNodes> newChildren = new ArrayList<>();
        for (CategoryTreeNodes child : node.getChildren()) {
            CategoryTreeNodes filteredChild = filterResourceUnderAuthorizedBuildings(child, authorizedBuildingIds);
            if (filteredChild != null) {
                newChildren.add(filteredChild);
            }
        }

        node.setChildren(newChildren);

        if (node.getType() == 5 || !newChildren.isEmpty()) {   //type=6  资源
            return node;
        }

        return null;
    }
}